﻿using System;
using System.Collections.Generic;
using MugenInjection.Delegates;
using MugenInjection.Infrastructure;

namespace MugenInjection.Interface
{
    /// <summary>
    ///     Represents the delegate that will handle events raised when a <c>Type</c> changed.
    /// </summary>
    /// <param name="sender">
    ///     The specified <see cref="IConverter" /> when type was changed.
    /// </param>
    /// <param name="action">The type of action.</param>
    /// <param name="type">The changed type.</param>
    public delegate void TypeChangedDelegate(IConverter sender, TypeChangedAction action, Type type);

    /// <summary>
    ///     Represents the interface that can convert types when binding activating.
    /// </summary>
    public interface IConverter
    {
        /// <summary>
        ///     Gets the service type of converter.
        /// </summary>
        ServiceType ServiceType { get; }

        /// <summary>
        ///     Gets the priority.
        /// </summary>
        int Priority { get; }

        /// <summary>
        ///     Gets the supported types.
        /// </summary>
        IEnumerable<Type> SupportedTypes { get; }

        /// <summary>
        ///     Tries to convert instance.
        /// </summary>
        /// <param name="bindingContext">The specified type to convert.</param>
        /// <param name="originalType">The result of convert.</param>
        /// <param name="convertAction">An delegate to convert instance.</param>
        /// <returns>
        ///     If <c>true</c> can be converted; otherwise <c>false</c>.
        /// </returns>
        ConverterResult TryConvert(IBindingContext bindingContext, out Type originalType, out Func<object, object> convertAction);

        /// <summary>
        /// Clears cache, if any.
        /// </summary>
        void ClearCache();

        /// <summary>
        ///     Occurs when the <c>SupportedTypes</c> changed.
        /// </summary>
        event TypeChangedDelegate SupportedTypeChanged;
    }
}